<template>
  <div class="student-container">
    <div class="app-container">
      <el-card class="box-card">

        <!-- 页头 -->
        <div
          slot="header"
          class="clearfix"
        >
          <span>学生管理</span>
          <div class="form">
            <div class="add">
              <el-button
                type="primary"
                @click="addStudentFn()"
              >添加学生</el-button>
            </div>
          </div>
        </div>

        <!-- 筛选 -->
        <div class="screen">
          <el-form
            :rules="screenRules"
            inline
            :model="query"
            ref="screenForm"
          >
            <el-form-item
              label="学部"
              prop="faculty"
            >
              <el-select
                filterable
                clearable
                v-model="query.faculty"
                placeholder="请选择学部"
                @change='screenSelectChange()'
              >
                <el-option
                  v-for="(item, index) in facultyOptions"
                  :key="index"
                  :value="item"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item
              label="年级"
              prop="grade"
            >
              <el-select
                filterable
                clearable
                v-model="query.grade"
                placeholder="请选择年级"
                @change='screenSelectChange()'
              >
                <el-option
                  v-for="(item, index) in gradeOptions"
                  :key="index"
                  :value="item"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item
              label="班级"
              prop="s_class"
            >
              <el-select
                filterable
                clearable
                v-model="query.s_class"
                placeholder="请选择班级"
              >
                <el-option
                  v-for="(item, index) in classOptions"
                  :key="index"
                  :value="item.name"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button
                type="primary"
                @click="screenSubmitFn()"
              >筛选</el-button>
              <el-button @click="screenResetFn()">重置</el-button>
            </el-form-item>
          </el-form>

          <el-form
            :inline="true"
            :model="queryForm"
            ref='queryForm'
            :rules='queryRules'
            class="query-form"
          >
            <el-form-item
              prop="s_number"
              label="学号"
            >
              <el-input
                v-model.trim="queryForm.s_number"
                placeholder="请输入查找学号"
                clearable
                @keyup.enter.native="getQueryFn()"
              ></el-input>
            </el-form-item>
            <el-form-item>
              <el-button
                type="primary"
                @click="getQueryFn()"
              >查询</el-button>
            </el-form-item>
          </el-form>
        </div>

        <!-- 表格组件 -->
        <div
          class="table"
          style="height:80%"
        >
          <el-table
            :data="studentList"
            style="width: 100%"
          >
            <el-table-column
              type="index"
              label="序号"
              min-width='50px'
            >
            </el-table-column>
            <el-table-column
              prop="s_number"
              label="学号"
              min-width='80px'
            >
            </el-table-column>
            <el-table-column
              prop="name"
              label="姓名"
              min-width='80px'
            >
            </el-table-column>
            <el-table-column
              prop="faculty"
              label="学部"
              min-width='100px'
            >
            </el-table-column>
            <el-table-column
              prop="grade"
              label="年级"
              min-width='80px'
            >
            </el-table-column>
            <el-table-column
              prop="s_class"
              label="班级"
              min-width='100px'
            >
            </el-table-column>
            <el-table-column
              prop="phone"
              label="手机号"
              min-width='100px'
            >
            </el-table-column>
            <el-table-column
              label="操作"
              width='165x'
              fixed='right'
            >
              <template v-slot="{row}">
                <el-button
                  circle
                  size="mini"
                  icon="el-icon-search"
                  @click="rowInfoFn(row)"
                ></el-button>
                <el-button
                  type="primary"
                  circle
                  icon="el-icon-edit"
                  size="mini"
                  @click="rowUpdateFn(row)"
                ></el-button>

                <el-popconfirm
                  title="确定删除该学生吗？如果有报修单属于该学生则无法删除！"
                  @confirm="rowDeleteFn(row)"
                >
                  <el-button
                    slot="reference"
                    type="danger"
                    circle
                    icon="el-icon-delete"
                    size="mini"
                  ></el-button>
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <!-- 分页组件 -->
        <el-row
          type="flex"
          justify="center"
          align="middle"
          style="height: 60px; margin-top: 40px;"
          v-if="total > query.pagesize"
        >
          <!-- 分页区域 -->
          <el-pagination
            :current-page="query.page"
            :page-sizes="[10, 15, 20, 25]"
            :page-size="query.size"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            hide-on-single-page
          />
        </el-row>

        <el-dialog
          title="学生信息"
          :visible.sync="dialogInfoVisible"
          @close="dialogCloseFn()"
          :show-close='false'
          custom-class='dialog-info-35'
        >
          <el-descriptions
            border
            :column='2'
            labelClassName="width-100"
          >
            <el-descriptions-item
              label="id号"
              span="2"
            >{{studentInfo.id}}</el-descriptions-item>
            <el-descriptions-item label="学号">{{studentInfo.s_number}}</el-descriptions-item>
            <el-descriptions-item label="姓名">{{studentInfo.name}}</el-descriptions-item>
            <el-descriptions-item label="学部">{{studentInfo.faculty}}</el-descriptions-item>
            <el-descriptions-item label="年级">{{studentInfo.grade}}</el-descriptions-item>
            <el-descriptions-item label="班级">{{studentInfo.s_class}}</el-descriptions-item>
            <el-descriptions-item label="手机号">{{studentInfo.phone}}</el-descriptions-item>
          </el-descriptions>
        </el-dialog>

        <el-dialog
          :title="isAdd ? '添加学生':'修改学生信息'"
          :visible.sync="dialogUpdateVisible"
          @close="dialogCloseFn()"
          :close-on-click-modal='false'
          :show-close='false'
          custom-class='dialog-30'
        >
          <el-form
            :model="studentInfo"
            status-icon
            :rules="studentRules"
            ref="studentInfo"
            label-width="60px"
          >
            <el-form-item
              label="学号"
              prop="s_number"
            >
              <el-input
                v-model.trim="studentInfo.s_number"
                @keyup.enter.native="updateSubmitFn()"
              ></el-input>
            </el-form-item>
            <el-form-item
              label="姓名"
              prop="name"
            >
              <el-input
                v-model.trim="studentInfo.name"
                @keyup.enter.native="updateSubmitFn()"
              ></el-input>
            </el-form-item>
            <el-form-item
              label="密码"
              prop="password"
              v-if="isAdd"
            >
              <el-input
                type="password"
                v-model.trim="studentInfo.password"
                clearable
                minlength="6"
                maxlength="12"
                show-password
                @keyup.enter.native="updateSubmitFn()"
              ></el-input>
            </el-form-item>
            <el-form-item
              label="手机号"
              prop="phone"
            >
              <el-input
                v-model.trim="studentInfo.phone"
                @keyup.enter.native="updateSubmitFn()"
              ></el-input>
            </el-form-item>
            <el-form-item
              label="学部"
              prop="faculty"
            >
              <el-select
                filterable
                clearable
                v-model="studentInfo.faculty"
                placeholder="请选择学部"
                @change='dialogSelectChange()'
              >
                <el-option
                  v-for="(item, index) in facultyOptions"
                  :key="index"
                  :value="item"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item
              label="年级"
              prop="grade"
            >
              <el-select
                filterable
                clearable
                v-model="studentInfo.grade"
                placeholder="请选择年级"
                @change='dialogSelectChange()'
              >
                <el-option
                  v-for="(item, index) in gradeOptions"
                  :key="index"
                  :value="item"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item
              label="班级"
              prop="s_class"
            >
              <el-select
                filterable
                clearable
                v-model="studentInfo.s_class"
                placeholder="请选择班级"
              >
                <el-option
                  v-for="(item, index) in classOptions"
                  :key="index"
                  :value="item.name"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item class="center">
              <el-button @click="dialogUpdateVisible = false">取消</el-button>
              <el-button
                type="primary"
                @click="updateSubmitFn()"
              >{{isAdd ? '添加':'修改'}}</el-button>
            </el-form-item>
          </el-form>
        </el-dialog>
      </el-card>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import {
  getStudentListAPI,
  queryStudentAPI,
  updateStudentAPI,
  deleteStudentAPI,
  addStudentAPI,
  getFacultyListAPI,
  getGradeListAPI,
  getClassListAPI
} from '@/api'
export default {
  name: 'studentList',
  computed: {
    ...mapGetters(['userInfo'])
  },
  data () {
    // 判断是有对应的学部
    const validFaculty = (rule, value, callback) => {
      value &&
        (this.facultyOptions.includes(value)
          ? callback()
          : callback(new Error('学部不存在')))
      callback()
    }
    // 判断是有对应的年级
    const validGrade = (rule, value, callback) => {
      value &&
        (this.gradeOptions.includes(value)
          ? callback()
          : callback(new Error('年级不存在')))
      callback()
    }
    // 判断是有对应的班级
    const validClass = (rule, value, callback) => {
      if (value) {
        this.classList.forEach((item) => {
          item.name === value && callback()
        })
        callback(new Error('班级不存在'))
      }
      callback()
    }
    return {
      query: {
        page: 1, // 页码
        pagesize: 10, // 每页条数
        faculty: '',
        grade: '',
        s_class: ''
      }, // 获取列表数据
      studentList: [], // 学生信息列表
      total: 0, // 总数
      queryForm: {
        s_number: ''
      }, // 查找数据
      queryRules: {
        s_number: [
          { required: true, message: '学号不能为空', trigger: 'blur' },
          {
            pattern: /^[0-9]{10,12}$/,
            message: '学号要求10-12个数字',
            trigger: 'blur'
          }
        ]
      }, // 查找数据验证
      dialogInfoVisible: false, // 信息展示 dialog 控制
      dialogUpdateVisible: false, // 修改信息 dialog 控制
      studentInfo: {
        s_class: ''
      }, // dialog 数据
      studentRules: {
        password: [
          { required: true, message: '密码不能为空！', trigger: 'change' },
          {
            min: 6,
            max: 12,
            type: 'string',
            message: '密码要求6-12个字符',
            trigger: 'change'
          }
        ],
        phone: [
          {
            pattern:
              /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,
            message: '请输入正确的手机号',
            trigger: 'change'
          }
        ],
        id: [
          { required: true, message: 'id不能为空', trigger: 'blur' },
          {
            length: '32',
            type: 'string',
            message: 'id格式有误',
            trigger: 'blur'
          }
        ],
        name: [
          { required: true, message: '姓名不能为空', trigger: 'blur' },
          {
            min: 2,
            max: 20,
            type: 'string',
            message: '姓名要求2-20个字符',
            trigger: 'blur'
          }
        ],
        s_number: [
          { required: true, message: '学号不能为空', trigger: 'blur' },
          {
            pattern: /^[0-9]{10,12}$/,
            message: '学号要求10-12个数字',
            trigger: 'blur'
          }
        ],
        faculty: [
          { required: true, message: '学部不能为空', trigger: 'change' },
          { validator: validFaculty, trigger: 'change' }
        ],
        grade: [
          { required: true, message: '年级不能为空', trigger: 'change' },
          { validator: validGrade, trigger: 'change' }
        ],
        s_class: [
          { required: true, message: '班级不能为空', trigger: 'change' },
          { validator: validClass, trigger: 'change' }
        ]
      }, // dialog 数据验证
      facultyOptions: [], // 筛选学部数据
      gradeOptions: [], // 筛选年级数据
      classList: [], // 班级类型数据
      classOptions: [], // 筛选班级类型数据
      screenRules: {
        faculty: [{ validator: validFaculty, trigger: 'blur' }],
        grade: [{ validator: validGrade, trigger: 'blur' }],
        s_class: [{ validator: validClass, trigger: 'blur' }]
      }, // 筛选数据验证
      isAdd: false // 是否是添加操作
    }
  },
  created () {
    this.getFacultyFn()
    this.getGradeFn()
    this.getClassFn()
    this.getStudentListFn()
  },
  methods: {
    // 每页显示的条数发生改变时触发
    handleSizeChange (newSize) {
      this.query.size = newSize
      this.getStudentListFn() // 获取学生列表
    },
    // 当前页面发生改变时触发
    handleCurrentChange (newPage) {
      this.query.page = newPage
      this.getStudentListFn() // 获取学生列表
    },
    // 获取学生列表 -> 发送请求
    async getStudentListFn () {
      try {
        const { success, code, data } = await getStudentListAPI(this.query)
        if (success && code === 10000) {
          this.studentList = data.row
          this.total = data.total
        }
      } catch (err) {
        return console.dir(err)
      }
    },
    // 获取学部 -> 发送请求
    async getFacultyFn () {
      try {
        const { success, code, data } = await getFacultyListAPI({
          page: 1
        })
        if (success && code === 10000) {
          data.row.forEach((item) => {
            this.facultyOptions.push(item.name)
          })
        }
      } catch (err) {
        return console.dir(err)
      }
    },
    // 获取年级 -> 发送请求
    async getGradeFn () {
      try {
        const { success, code, data } = await getGradeListAPI({
          page: 1
        })
        if (success && code === 10000) {
          data.row.forEach((item) => {
            this.gradeOptions.push(item.name)
          })
        }
      } catch (err) {
        return console.dir(err)
      }
    },
    // 获取班级 -> 发送请求
    async getClassFn () {
      try {
        const { success, code, data } = await getClassListAPI({
          page: 1
        })
        if (success && code === 10000) {
          data.row.forEach((item, index) => {
            this.classList.push(item)
            delete this.classList[index].id
          })
        }
      } catch (err) {
        return console.dir(err)
      }
    },
    // 根据输入学号查询
    async getQueryFn () {
      this.$refs.queryForm.validate(async (valid) => {
        if (valid) {
          try {
            const { success, code, data } = await queryStudentAPI(
              this.queryForm
            )
            if (success && code === 10000) {
              this.studentList = [data]
            }
          } catch (err) {
            return console.dir(err)
          }
        }
      })
    },
    // 点击查看 -> 展示数据详情
    rowInfoFn (row) {
      this.studentInfo = row
      this.dialogInfoVisible = true
    },
    // 点击修改 -> 展示数据 -> 修改
    rowUpdateFn (row) {
      this.studentInfo = { ...row }
      this.isAdd = false
      this.dialogUpdateVisible = true
    },
    // 点击删除 -> 删除该学生
    async rowDeleteFn (row) {
      try {
        const { success, code } = await deleteStudentAPI(row.id)
        if (success && code === 10000) {
          success && this.getStudentListFn()
        }
      } catch (err) {
        return console.dir(err)
      }
    },
    // dialog 关闭
    dialogCloseFn () {
      this.studentInfo = this.$options.data().studentInfo
      this.$refs.studentInfo?.resetFields()
    },
    // dialog 点击添加/修改 -> 发起请求
    async updateSubmitFn () {
      this.$refs.studentInfo.validate(async (valid) => {
        if (valid) {
          try {
            delete this.studentInfo.state
            let success, code
            if (this.isAdd) {
              ; ({ success, code } = await addStudentAPI(this.studentInfo))
            } else {
              ; ({ success, code } = await updateStudentAPI(this.studentInfo))
            }

            if (success && code === 10000) {
              this.dialogUpdateVisible = false
              this.getStudentListFn()
            }
          } catch (err) {
            return console.dir(err)
          }
        }
      })
    },
    // 点击筛选按钮 -> 重新获取列表
    screenSubmitFn () {
      this.$refs.screenForm.validate(async (valid) => {
        valid && this.getStudentListFn()
      })
    },
    // 清空筛选数据 -> 重新获取列表
    screenResetFn () {
      this.query = this.$options.data().query
      this.$refs.screenForm?.resetFields()
      this.getStudentListFn()
    },
    // 点击添加按钮
    addStudentFn () {
      this.isAdd = true
      this.dialogUpdateVisible = true
    },
    // dialog 中选择器值发生变化
    dialogSelectChange () {
      this.studentInfo.s_class = ''
      if (this.studentInfo.faculty || this.studentInfo.grade) {
        this.classOptions = this.classList.filter((item) => {
          if (
            this.studentInfo.faculty &&
            item.faculty !== this.studentInfo.faculty
          ) {
            return false
          }
          if (this.studentInfo.grade && item.grade !== this.studentInfo.grade) {
            return false
          }
          return true
        })
      }
    },
    // 筛选栏中选择器值发生变化
    screenSelectChange () {
      delete this.query.s_class
      if (this.query.faculty || this.query.grade) {
        this.classOptions = this.classList.filter((item) => {
          if (this.query.faculty && item.faculty !== this.query.faculty) {
            return false
          }
          if (this.query.grade && item.grade !== this.query.grade) return false
          return true
        })
      }
    }
  }
}
</script>

<style lang="less" scoped>
.clearfix {
  display: flex;
}
.form {
  text-align: right;
  flex-grow: 1;
}
.title {
  flex-grow: 0;
}
.form {
  display: flex;
  justify-content: right;
}
.screen {
  display: flex;
  flex-wrap: wrap;
}
</style>
